package org.example.rmsmsapi.Utils;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.bouncycastle.jce.provider.BouncyCastleProvider;
import org.bouncycastle.pqc.math.linearalgebra.ByteUtils;
import org.bouncycastle.util.encoders.Hex;
import org.springframework.stereotype.Service;

import javax.crypto.Cipher;
import javax.crypto.KeyGenerator;
import javax.crypto.SecretKey;
import javax.crypto.spec.SecretKeySpec;
import java.nio.charset.StandardCharsets;
import java.security.Security;
import java.util.Base64;
import java.util.HashMap;
import java.util.Map;

import static java.lang.Character.UnicodeBlock.of;

@Service
public class Sm4Method {
    static {
        // 添加Bouncy Castle提供者
        Security.addProvider(new BouncyCastleProvider());
    }

    // SM4算法参数
    private static final String ALGORITHM_NAME = "SM4";
    //算法sm4/模式ECB/填充PKCS5Padding
    private static final String ALGORITHM_NAME_ECB_PADDING = "SM4/ECB/PKCS5Padding";
    private static final int DEFAULT_KEY_SIZE = 128;
    private static final String ENCODING = "UTF-8";
    private Character.UnicodeBlock HexFormat;

    /**
     * 生成SM4密钥
     */
    public static byte[] generateKey() throws Exception {
        KeyGenerator kg = KeyGenerator.getInstance(ALGORITHM_NAME, BouncyCastleProvider.PROVIDER_NAME);
        kg.init(DEFAULT_KEY_SIZE);
        SecretKey secretKey = kg.generateKey();
        return secretKey.getEncoded();

    }

    /**
     * SM4加密
     */
    public static byte[] encrypt(byte[] data, byte[] key) throws Exception {
        SecretKeySpec secretKeySpec = new SecretKeySpec(key, ALGORITHM_NAME);
        Cipher cipher = Cipher.getInstance(ALGORITHM_NAME_ECB_PADDING, BouncyCastleProvider.PROVIDER_NAME);
        cipher.init(Cipher.ENCRYPT_MODE, secretKeySpec);
        return cipher.doFinal(data);
    }

    /**
     * SM4解密
     */
    public static byte[] decrypt(byte[] encryptedData, byte[] key) throws Exception {
        SecretKeySpec secretKeySpec = new SecretKeySpec(key, ALGORITHM_NAME);
        Cipher cipher = Cipher.getInstance(ALGORITHM_NAME_ECB_PADDING, BouncyCastleProvider.PROVIDER_NAME);
        cipher.init(Cipher.DECRYPT_MODE, secretKeySpec);
        return cipher.doFinal(encryptedData);
    }

    /*解密数据*/
    public void Sm4DecryptEcb(String date) throws Exception {

        System.out.println("解密前测试数据date:" +date);
        // 4. 解密数据
        byte[] key1 = Hex.decode("0123456789ABCDEFFEDCBA9876543210");//固定解密秘钥
        // 4. 解密数据
        // 加密后的字节数组 -> Base64字符串（适合传输/存储）
        //String encryptedStr = Base64.getEncoder().encodeToString(encrypted);
        // 还原：Base64字符串 -> 字节数组（用于解密）
        byte[] encryptedBytes = Base64.getDecoder().decode(date);
        byte[] decrypted;
        decrypted = decrypt(encryptedBytes, key1);
        String decryptedJson = new String(decrypted);
        System.out.println("解密后的JSON: " + decryptedJson);

/*
        // 5. 解析回Map对象
        Map<String, String> decryptedData = objectMapper.readValue(decryptedJson, Map.class);
        System.out.println("解析后的数据 - name: " + decryptedData.get("name") +
                ", sex: " + decryptedData.get("sex"));
*/
}

    /*加密数据*/
    public String Sm4EncryptEcb() throws Exception {
        // 1. 生成SM4密钥
        //@zhoubin
        //byte[] key = generateKey();//随机生成动态秘钥
        byte[] key = Hex.decode("0123456789ABCDEFFEDCBA9876543210");//固定秘钥
        System.out.println("生成的SM4固定密钥: " + Hex.toHexString(key));


        // 2. 创建包含name和sex的JSON对象
        Map<String, String> jsonData = new HashMap<>();
        jsonData.put("name", "周斌");
        jsonData.put("sex", "男");
        //jsonData.put("ID", "111");

        ObjectMapper objectMapper = new ObjectMapper();
        String jsonString = objectMapper.writeValueAsString(jsonData);
        System.out.println("原始JSON: " + jsonString);

        // 3. 加密JSON字符串
        byte[] encrypted = encrypt(jsonString.getBytes(), key);
        //String decryptStr = new String(encrypted, ENCODING);
        String encryptedStr = Base64.getEncoder().encodeToString(encrypted);
/*
        // 4. 解密数据
        // 加密后的字节数组 -> Base64字符串（适合传输/存储）
        String encryptedStr = Base64.getEncoder().encodeToString(encrypted);
        // 还原：Base64字符串 -> 字节数组（用于解密）
        byte[] encryptedBytes = Base64.getDecoder().decode(encryptedStr);
        byte[] decrypted;
        decrypted = decrypt(encryptedBytes, key);
        String decryptedJson = new String(decrypted);
        System.out.println("解密后的JSON: " + decryptedJson);
*/
        return encryptedStr;

    }
}
